﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Skyhook.Logic.VisualControllers;
using Skyhook.Isometry;
using Skyhook.Core;
using System.Diagnostics;
using Skyhook.AI.PathFinder;
using Skyhook.AI;
using Skyhook.Core.Helpers;

namespace Skyhook.Logic
{
    public class LogicEngine : Microsoft.Xna.Framework.GameComponent
    {
        int[] nums = new int[1];

        int NumEnemyTanks = 0;
        int[] TargetTime;
        int[] State;
        int[] ElapsedTime;
        float EnemyTankRadius = 0.4f;
        float[] EnemyTankSpeed;

        TimingData TimingData = new TimingData();

        Units.Tank[] enemies = null;
        Units.Animation[] expl = null;
        int NumAnimations = 0;

        Units.Tank player = null;
        Units.Animation explosion = null;

        const float Sqrt3 = 1.73205f;
        //const float Sqrt3 = 2.00f;

        float TX, TY;

        bool moving = false;
        
        public LogicEngine(Microsoft.Xna.Framework.Game game): base(game)
        {
        }

        public override void Initialize()
        {
            player = new Units.Tank("landobj", 1, 1, 0.02f,8.0f);
            //Units.HugeObjects house1 = new Units.HugeObjects("house", 4.5f, 4.5f);
            //explosion = Units.Animation.None;
            //explosion = new Units.Animation("expl", 10, 10);
            //explosion.StartMove(0.05f,new Vector2(25,25));

            Random random = new Random();

            enemies = new Units.Tank[NumEnemyTanks];
            TargetTime = new int[NumEnemyTanks];
            ElapsedTime = new int[NumEnemyTanks];
            State = new int[NumEnemyTanks];
            for (int i = 0; i < NumEnemyTanks; i++)
            {
                //enemies[i] = new Units.Tank("panther", i % 128, i / 128, 0.05f, 0.1f);
                enemies[i] = new Units.Tank("panther", random.Next(127), random.Next(127), 0.08f, 2.0f);
                State[i] = 0;
                ElapsedTime[i] = 0;
                TargetTime[i] = 4000 + random.Next(10000);
                enemies[i].Num = i;
                enemies[i].OnStopEvent += TankTimeUpdate;
            }
            expl = new Units.Animation[10000];

            BlockingMap map = new BlockingMap(128, 128);
            for (int i = 0; i < 0; i++)
            {
                int x = random.Next(127);
                int y = random.Next(127);
                Units.HugeObjects house = new Units.HugeObjects("house", 0.5f + x, 0.5f + y);
                
                map.SetBlocked(x - 2, y);
                map.SetBlocked(x - 1, y);
                map.SetBlocked(x, y);
                map.SetBlocked(x - 2, y - 1);
                map.SetBlocked(x - 1, y - 1);
                map.SetBlocked(x, y - 1);
                map.SetBlocked(x - 2, y - 2);
                map.SetBlocked(x - 1, y - 2);
                map.SetBlocked(x, y - 2);
            }

            
            PathFinder.Initialize(map);
            PathFinder.Start();

            TimingData.Initialize(15);

            base.Initialize();
        }

        void TankTimeUpdate(MovableObject<TankVisualController> sender)
        {
            Units.Tank tank = (Units.Tank)sender;
            ElapsedTime[tank.Num] = 0;
            State[tank.Num] = 0;
        }

        public override void Update(GameTime gameTime)
        {
            TimingData.Update(gameTime);
            Random random = new Random();
            player.Update(TimingData.Scale);
            //WorldCamera.Put((int)IsoUtils.ConvertWorldToScreen(player.X, player.Y).X, (int)IsoUtils.ConvertWorldToScreen(player.X, player.Y).Y);
            //explosion.Update(TimingData.Scale);
            foreach (Units.Tank tank in enemies)
            {
                tank.Update(TimingData.Scale);
                if (State[tank.Num] == 0)
                {
                    ElapsedTime[tank.Num] += gameTime.ElapsedGameTime.Milliseconds;
                    if (ElapsedTime[tank.Num] >= TargetTime[tank.Num])
                    {
                        tank.MoveToPoint(random.Next(127), random.Next(127));
                        State[tank.Num] = 1;

                        ElapsedTime[tank.Num] = 0;
                    }
                }
            }

            base.Update(gameTime);
        }

        virtual public void OnKeyPressed(Keys key)
        {
            if (key == Keys.W)
            {
                player.MoveToPoint(0,0);
                /*foreach (Units.Tank tank in enemies)
                {
                    tank.MoveController.MoveToPoint(new Vector2(64.5f, 64.5f));
                }*/
            }
            if (key == Keys.S)
            {
                player.MoveToPoint(2, 2);
                /*foreach (Units.Tank tank in enemies)
                {
                    tank.StopMove();
                }*/
            }
            if (key == Keys.Q)
            {
                player.MoveToPoint(5, 5);
                /*foreach (Units.Tank tank in enemies)
                {
                    tank.MoveController.MoveToPoint(new Vector2(64.5f, 64.5f));
                }*/
            }
            if (key == Keys.E)
            {
                player.MoveToPoint(5, 5);
                /*foreach (Units.Tank tank in enemies)
                {
                    tank.MoveController.MoveToPoint(new Vector2(64.5f, 64.5f));
                }*/
            }
            if (key == Keys.A)
            {
                player.MoveToPoint(5, 5);
            }
            if (key == Keys.D)
            {
                player.MoveToPoint(5, 5);
            }
            if (key == Keys.Z)
            {
                player.MoveToPoint(5, 5);
            }            
            if (key == Keys.C)
            {
                Stopwatch timer = new Stopwatch();
                timer.Start();
                //player.MoveToPoint(5, 5);
                foreach (Units.Tank tank in enemies)
                {
                    tank.MoveToPoint(5, 5);
                }
                timer.Stop();

                //Global.Debug.WriteDebugString("Time = " + timer.ElapsedMilliseconds,TimeSpan.FromSeconds(10));
            }
            if (key == Keys.R)
            {
                
            }
            if (key == Keys.Escape)
            {
                
            }

            /*if (key == Keys.E)
            {
                expl = new Units.Animation[1000];
                Random random = new Random();
                for (int i = 0; i < 1000; i++)
                {
                    expl[i] = new Units.Animation("expl", 0.5f + random.Next(127), 0.5f + random.Next(127));
                }
            }*/

            if (key == Keys.Left)
            {
                WorldCamera.Move(-50, 0);
            }
            if (key == Keys.Right)
            {
                WorldCamera.Move(50, 0);
            }
            if (key == Keys.Up)
            {
                WorldCamera.Move(0, -50);
            }
            if (key == Keys.Down)
            {
                WorldCamera.Move(0, 50);
            }
            if (key == Keys.Space)
            {
                if (!moving)
                {
                    moving = true;
                }
                else
                {
                    moving = false;
                }
            }
        }
        virtual public void OnKeyDown(Keys key)
        {
            if (key == Keys.W)
            {
                
            }
            if (key == Keys.S)
            {
                
            }
            if (key == Keys.A)
            {
                
            }
            if (key == Keys.D)
            {
                
            }
        }
        virtual public void OnMouseMove(int x, int y)
        {
            //player.RotateTurretToPoint(new Vector2(IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).X, IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).Y));
        }
        virtual public void OnMouseLDown(int x, int y)
        {
           
        }
        virtual public void OnMouseRDown(int x, int y)
        {

        }
        virtual public void OnMouseLClick(int x, int y)
        {
            //explosion = new Units.Animation("expl", IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).X, IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).Y);
            //explosion.Start();
        }
        virtual public void OnMouseRClick(int x, int y)
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();
            player.MoveToPoint((int)IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).X, (int)IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).Y);
            /*foreach (Units.Tank tank in enemies)
            {
                tank.MoveToPoint((int)IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).X, (int)IsoUtils.ConvertScreenToWorld(x + WorldCamera.Left, y + WorldCamera.Top).Y);
            }*/
            timer.Stop();

            //Global.Debug.WriteDebugString("Time = " + timer.ElapsedMilliseconds, TimeSpan.FromSeconds(10));
        }
    }
}
